import * as THREE from "three";
// 引入轨道控制器扩展库OrbitControls.js
import { OrbitControls } from "three/addons/controls/OrbitControls.js";
//引入性能监视器stats.js
import Stats from "three/addons/libs/stats.module.js";

const stats = new Stats();

// stats.domElement显示：渲染帧率  刷新频率,一秒渲染次数
// stats.setMode(0);//默认模式
//stats.domElement显示：渲染周期 渲染一帧多长时间(单位：毫秒ms)
stats.setMode(1);

const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(
  45,
  window.innerWidth / window.innerHeight,
  0.1,
  1000
);
const renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);

// ------------------------------------------------

// 多边形轮廓Shape
// Shape的父类是Path,Path提供了直线、圆弧、贝塞尔、样条等绘制方法，Shape也会从父类是Path继承这些图形绘制方法

// Shape表示一个平面多边形轮廓
// const shape = new THREE.Shape([
//   // 按照特定顺序，依次书写多边形顶点坐标
//   new THREE.Vector2(-50, -50), //多边形起点
//   new THREE.Vector2(-50, 50),
//   new THREE.Vector2(50, 50),
//   new THREE.Vector2(50, -50),
// ]);
// const shape = new THREE.Shape()
// const path = new THREE.Path();
// shape.moveTo(10, 0); //.currentPoint变为(10,0)
// // 绘制直线线段，起点(10,0)，结束点(100,0)
// shape.lineTo(100, 0);//.currentPoint变为(100, 0)
// shape.lineTo(100, 100);//.currentPoint变为(100, 100)
// shape.lineTo(10, 100);//.currentPoint变为(10, 100)
// console.log('currentPoint',shape.currentPoint);
// // const geometry = new THREE.ShapeGeometry(shape);
// // .currentPoint属性字面意思是当前点，默认值Vector2(0,0)。
// // ExtrudeGeometry拉伸Shape获得一个长方体几何体
// const geometry = new THREE.ExtrudeGeometry(shape, {
//   depth:20,//拉伸长度
//   bevelEnabled:false,//禁止倒角
// });

//  多边形轮廓Shape(圆弧)
// 下面代码绘制了一个矩形+扇形的轮廓，圆心在(100, 0),半径50。
// const shape = new THREE.Shape();
// shape.lineTo(100 + 50, 0); //.currentPoint变为(100+50,0)
// 圆弧.arc参数的圆心0,0坐标是相对当前.currentPoint而言，而不是坐标原点
// shape.arc(-50, 0, 50, 0, Math.PI / 2); //.currentPoint变为圆弧线结束点坐标
// console.log("currentPoint", shape.currentPoint);
// 绘制直线，直线起点：圆弧绘制结束的点  直线结束点：(0, 0)
// shape.lineTo(0, 50);
// shape:填充轮廓  
// const geometry = new THREE.ShapeGeometry(shape, 20);
// const geometry = new THREE.ExtrudeGeometry(shape, {
//   depth:20,//拉伸长度
//   bevelEnabled:false,//禁止倒角
//   curveSegments:20,//shape曲线对应曲线细分数
// });

// 多边形Shape(内孔.holes)
// 先创建Shape的矩形外轮廓。
// const shape = new THREE.Shape();
// // .lineTo(100, 0)绘制直线线段，线段起点：.currentPoint，线段结束点：(100,0)
// shape.lineTo(100, 0);
// shape.lineTo(100, 100);
// shape.lineTo(0, 100);
// // Shape内孔轮廓
// const path1 = new THREE.Path();// 圆孔1
// path1.absarc(20, 20, 10);
// const path2 = new THREE.Path();// 圆孔2
// path2.absarc(80, 20, 10);
// const path3 = new THREE.Path();// 方形孔
// path3.moveTo(50, 50);
// path3.lineTo(80, 50);
// path3.lineTo(80, 80);
// path3.lineTo(50, 80);

// shape.holes.push(path1, path2,path3);
// const geometry = new THREE.ExtrudeGeometry(shape, {
//   depth:20,//拉伸长度
//   bevelEnabled:false,//禁止倒角
//   curveSegments:50,
// });

const geometry = new THREE.BoxGeometry(50, 50, 50);
const material = new THREE.MeshLambertMaterial({
    color: 0x00ffff,
    transparent:true,
    opacity:0.5,
});
const mesh = new THREE.Mesh(geometry, material);

// 长方体作为EdgesGeometry参数创建一个新的几何体
const edges = new THREE.EdgesGeometry(geometry);
const edgesMaterial = new THREE.LineBasicMaterial({
  color: 0x00ffff,
})
const line = new THREE.LineSegments(edges, edgesMaterial);
mesh.add(line);

scene.add(mesh)



// const material = new THREE.MeshLambertMaterial({
//   side: THREE.FrontSide, //双面显示看到管道内壁
//   color: 0x00ffff,
// });
// // THREE.FrontSide 仅渲染几何体的正面。这是默认行为，意味着只有当观察者从多边形顶点按照顺时针顺序定义的那一面看过去时，才能看到材质。
// // THREE.BackSide ：仅渲染几何体的背面。这意味着只有当观察者从多边形顶点按照逆时针顺序定义的那一面看过去时，才能看到材质
// // THREE.DoubleSide ：同时渲染几何体的正面和背面。这对于创建诸如窗户、纸张等双面都可见的对象非常有用。
// const line = new THREE.Mesh(geometry, material);

// scene.add(line);
// -----------------------------------------------
// 设置相机的位置以便更好地查看线段
camera.position.z = 200;
camera.position.y = 200;
camera.position.x = 200;
// 渲染循环
function animate() {
  requestAnimationFrame(animate);
  renderer.render(scene, camera);
}
animate();

const axesHelper = new THREE.AxesHelper(150);

// 添加辅助坐标系
scene.add(axesHelper);

// width和height用来设置Three.js输出的Canvas画布尺寸(像素px)
// const width = window.innerWidth; //窗口文档显示区的宽度作为画布宽度
// const height = window.innerHeight; //窗口文档显示区的高度作为画布高度

//点光源：两个参数分别表示光源颜色和光照强度
const pointLight = new THREE.PointLight(0xffffff, 1.0);
pointLight.decay = 1.0; //设置光源距离衰减

// 你可以对比不同光照强度明暗差异(传播同样距离)
pointLight.intensity = 100.0; //光照强度
// pointLight.intensity = 50000.0;//光照强度

//点光源位置 ,放在x轴上
// pointLight.position.set(0, 400, 400);
// pointLight.position.set(100, 60, 50);
pointLight.position.set(100, 50, 75);

//点光源添加到场景中
// scene.add(pointLight);

// 光源辅助观察
// const pointLightHelper = new THREE.PointLightHelper(pointLight, 10);
// scene.add(pointLightHelper);

//环境光:没有特定方向，整体改变场景的光照明暗
const ambient = new THREE.AmbientLight(0xffffff, 0.1);
scene.add(ambient);

// 平行光
const directionalLight = new THREE.DirectionalLight(0xffffff, 1);
// 设置光源的方向：通过光源position属性和目标指向对象的position属性计算
directionalLight.position.set(80, 100, 50);
// directionalLight.position.set(100, 0, 0);
// directionalLight.position.set(0, 100, 0);
// directionalLight.position.set(100, 100, 100);
// directionalLight.position.set(100, 60, 50);
// 方向光指向对象网格模型mesh，可以不设置，默认的位置是0,0,0
// directionalLight.target = mesh;
// scene.add(directionalLight);

// DirectionalLightHelper：可视化平行光
// const dirLightHelper = new THREE.DirectionalLightHelper(
//   directionalLight,
//   5,
//   0xff0000
// );
// scene.add(dirLightHelper);

// 设置相机控件轨道控制器OrbitControls
const controls = new OrbitControls(camera, renderer.domElement);
// 启用阻尼效果
controls.enableDamping = true;
controls.dampingFactor = 0.05;

// 如果OrbitControls改变了相机参数，重新调用渲染器渲染三维场景
controls.addEventListener("change", function () {
  renderer.render(scene, camera); //执行渲染操作
  // 浏览器控制台查看相机位置变化
  // console.log("camera.position", camera.position);
});

//执行渲染操作
renderer.render(scene, camera);

// Canvas画布插入到任意HTML元素中
// document.getElementById("webgl").appendChild(renderer.domElement);

document.body.appendChild(renderer.domElement);
document.body.appendChild(stats.domElement);

// 渲染函数
function render() {
  renderer.render(scene, camera); //执行渲染操作
  // mesh.rotateY(0.01); //每次绕y轴旋转0.01弧度
  controls.update(); // 必须调用此方法，以便阻尼效果生效
  stats.update(); //requestAnimationFrame循环调用的函数中调用方法update(),来刷新时间
  requestAnimationFrame(render); //请求再次执行渲染函数render，渲染下一帧
}
render();

window.onresize = function () {
  // 重置渲染器输出画布canvas尺寸
  renderer.setSize(window.innerWidth, window.innerHeight);
  // 全屏情况下：设置观察范围长宽比aspect为窗口宽高比
  camera.aspect = window.innerWidth / window.innerHeight;
  // 渲染器执行render方法的时候会读取相机对象的投影矩阵属性projectionMatrix
  // 但是不会每渲染一帧，就通过相机的属性计算投影矩阵(节约计算资源)
  // 如果相机的一些属性发生了变化，需要执行updateProjectionMatrix ()方法更新相机的投影矩阵
  camera.updateProjectionMatrix();
};

// console.log(THREE);
